//
//  TestRSA.m
//  OpenSSLDemo
//
//  Created by Andney Jack on 2021/2/28.
//

#import "TestRSA.h"
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/md5.h>

@implementation TestRSA
{
    RSA *_rsa;
}

- (NSData *)decryptRSAKeyWithType:(RSAKeyType)keyType paddingType:(int)padding encryptedData:(NSData *)data {
    if (data && [data length]) {
        int blockLength = 128;//解密必须是这个长度
        int sumLen = (int)[data length];
        int blockCount = sumLen / blockLength + 1;
        NSMutableData *sumData = [[NSMutableData alloc ] initWithCapacity:0];
        for (int i = 0; i < blockCount; i++) {
            int flen = MIN(blockLength, sumLen - i * blockLength);
            unsigned char from[flen];
            bzero(from, sizeof(from));
            memcpy(from, [[data subdataWithRange:NSMakeRange(i * blockLength, flen)] bytes], flen);
            unsigned char to[128];
            bzero(to, sizeof(to));

            [self decryptRSAKeyWithType:keyType from:from flen:flen to:to padding:padding];
            int k = 0;
            for (int j = 0; j < 128; j++) {
                if (to[j] != '\0') {
                    k = j + 1;
                }
            }//取出to数组的有效内容长度，不能用strlen，因为to为unsigned char*型，可能有效内容之间也有“\0”

            if (k % 4 != 0) {
                k = ((int)(k / 4) + 1) * 4;
            }
            [sumData appendData:[NSData dataWithBytes:to length:k]];
        }

        return sumData;
    }
    return nil;
}

- (int)decryptRSAKeyWithType:(RSAKeyType)keyType from:(const unsigned char *)from flen:(int)flen to:(unsigned char *)to padding:(int)padding {
    if (from != NULL && to != NULL) {
        int status;
        switch (keyType) {
            case RSAKeyTypePrivate: {
                //start encrypt
                status =  RSA_private_decrypt(flen, from, to, _rsa,  padding);
            }
            break;

            default: {
                //start encrypt
                status =  RSA_public_decrypt(flen, from, to, _rsa,  padding);
            }
            break;
        }

        return status;
    }
    return -1;
}

- (int)encryptRSAKeyWithType:(RSAKeyType)keyType from:(const unsigned char *)from flen:(int)flen to:(unsigned char *)to padding:(int)padding {
    if (from != NULL && to != NULL) {
        int status;

        switch (keyType) {
            case RSAKeyTypePrivate: {
                //start encrypt
                status =  RSA_private_encrypt(flen, from, to, _rsa,  padding);
            }
            break;

            default: {
                //start encrypt
                status =  RSA_public_encrypt(flen, from, to, _rsa,  padding);
            }
            break;
        }

        return status;
    }
    return -1;
}

- (NSData *)encryptRSAKeyWithType:(RSAKeyType)keyType paddingType:(int)padding data:(NSData *)d {
    if (d && [d length] > 0) {
        NSLog(@"sumlenth = %ld", [d length]);

        int blockLength = 128 - 11; // 加密必须是这个长度
        int sumLen = (int)[d length];
        int blockCount = sumLen / blockLength + 1;

        NSMutableData *sumData = [[NSMutableData alloc ] initWithCapacity:0];
        for (int i = 0; i < blockCount; i++) {
            int flen = MIN(blockLength, sumLen - i * blockLength);
            unsigned char from[flen];
            bzero(from, sizeof(from));
            memcpy(from, [[d subdataWithRange:NSMakeRange(i * blockLength, flen)] bytes], flen);
            unsigned char to[128];
            bzero(to, sizeof(to));

            [self encryptRSAKeyWithType:keyType from:from flen:flen to:to padding:padding];
            int k = 0;
            for (int j = 0; j < 128; j++) {
                if (to[j] != '\0') {
                    k = j + 1;
                }
            } // 取出to数组的有效内容长度，不能用strlen，因为to为unsigned char*型，可能有效内容之间也有“\0”

            if (k % 4 != 0) {
                k = ((int)(k / 4) + 1) * 4;
            }

            [sumData appendData:[NSData dataWithBytes:to length:k]];
        }

        return sumData;
    }
    return nil;
}

@end
